import { useMemo, useState, useEffect, useCallback, useRef } from 'react';
import { groupBy, orderBy, flatMap } from 'lodash';
import { message } from 'antd';
import Icon from '@ant-design/icons';
import ReloadOutlined from '@ant-design/icons/ReloadOutlined';
import { CopilotSVG } from '@/utils/svgs';
import { isRecommendedFinished } from '@/hooks/useAskPrompt';
import {
  ResultQuestion,
  RecommendedQuestionsTaskStatus,
} from '@/apollo/client/graphql/__types__';
import {
  useGetProjectRecommendationQuestionsLazyQuery,
  useGenerateProjectRecommendationQuestionsMutation,
} from '@/apollo/client/graphql/home.generated';
import { createLogger } from '../utils/logger';

const logger = createLogger('useRecommendedQuestionsInstruction');

const POLL_INTERVAL = 10000;
const MAX_RETRIES = 30;
const INITIAL_RETRY_DELAY = 2000;

export interface GroupedQuestion {
  category: string;
  question: string;
  sql: string;
}

const getGroupedQuestions = (
  questions: ResultQuestion[],
): GroupedQuestion[] => {
  if (!questions) {
    logger.warn('Questions is null or undefined');
    return [];
  }

  if (!Array.isArray(questions)) {
    logger.warn('Invalid questions format (not an array):', questions);
    return [];
  }

  try {
    // 确保每个问题都有必要的字段
    const validQuestions = questions
      .filter((q) => q && typeof q === 'object' && 'question' in q)
      .map((q) => ({
        question: q.question,
        category: q.category || 'General',
        sql: q.sql || '', // 确保sql字段存在
      }));

    if (validQuestions.length === 0) {
      logger.warn('No valid questions found after filtering');
      return [];
    }

    const groupedData = groupBy(validQuestions, 'category');
    return orderBy(
      flatMap(groupedData),
      (item) => groupedData[item.category]?.length || 0,
      'desc',
    );
  } catch (error) {
    logger.error('Error grouping questions:', error);
    return [];
  }
};

export default function useRecommendedQuestionsInstruction() {
  const [showRetry, setShowRetry] = useState<boolean>(false);
  const [generating, setGenerating] = useState<boolean>(false);
  const [isRegenerate, setIsRegenerate] = useState<boolean>(false);
  const [
    showRecommendedQuestionsPromptMode,
    setShowRecommendedQuestionsPromptMode,
  ] = useState<boolean>(false);
  const [recommendedQuestions, setRecommendedQuestions] = useState<
    GroupedQuestion[]
  >([]);
  const retryCountRef = useRef<number>(0);
  const isPollingRef = useRef<boolean>(false);
  const lastRequestIdRef = useRef<string | null>(null);
  const pollingTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  const pollingStartTimeRef = useRef<number>(0);

  const clearPollingTimeout = useCallback(() => {
    if (pollingTimeoutRef.current) {
      clearTimeout(pollingTimeoutRef.current);
      pollingTimeoutRef.current = null;
    }
  }, []);

  const stopPolling = useCallback(() => {
    clearPollingTimeout();
    isPollingRef.current = false;
  }, [clearPollingTimeout]);

  useEffect(() => {
    return () => {
      stopPolling();
    };
  }, [stopPolling]);

  const handlePollingError = useCallback(
    (error: any) => {
      if (retryCountRef.current >= MAX_RETRIES) {
        logger.warn('Max retries reached, stopping polling');
        stopPolling();
        setGenerating(false);
        setShowRetry(true);
        message.error('获取推荐问题失败，请重试');
        return;
      }

      retryCountRef.current += 1;
      logger.debug(`Retry attempt ${retryCountRef.current}/${MAX_RETRIES}`);
    },
    [stopPolling],
  );

  const handleBackendError = useCallback(
    (error: any) => {
      logger.error('Backend error:', error);
      stopPolling();
      setGenerating(false);
      setShowRetry(true);

      // 处理特定错误类型
      if (error.message?.includes('already exists')) {
        message.error('任务已存在，请稍后再试');
      } else if (error.message?.includes('not found')) {
        message.error('任务不存在，请重试');
      } else {
        message.error('创建提问任务失败，请重试');
      }
    },
    [stopPolling],
  );

  const [fetchRecommendationQuestions] =
    useGetProjectRecommendationQuestionsLazyQuery({
      fetchPolicy: 'network-only',
      onError: (error) => {
        logger.error('Query error:', error);
        handlePollingError(error);
      },
    });

  const [generateProjectRecommendationQuestions] =
    useGenerateProjectRecommendationQuestionsMutation({
      onError: (error) => {
        logger.error('Mutation error:', error);
        handleBackendError(error);
      },
      onCompleted: (data) => {
        logger.info('Mutation completed:', data);
      },
    });

  const fetchRecommendationQuestionsWithId = useCallback(async () => {
    if (!lastRequestIdRef.current) {
      logger.error('尝试获取推荐问题，但没有有效的请求ID');
      throw new Error('没有有效的请求ID');
    }

    try {
      logger.debug(`获取推荐问题，请求ID: ${lastRequestIdRef.current}`);
      const result = await fetchRecommendationQuestions();
      return result;
    } catch (error) {
      logger.error(
        `获取推荐问题失败，请求ID: ${lastRequestIdRef.current}`,
        error,
      );
      throw error;
    }
  }, [fetchRecommendationQuestions]);

  const startPolling = useCallback(() => {
    if (!isPollingRef.current) {
      logger.debug('轮询已停止');
      return;
    }

    // 检查是否超过最大轮询时间（5分钟）
    const currentTime = Date.now();
    const pollingDuration = currentTime - pollingStartTimeRef.current;
    if (pollingDuration > 5 * 60 * 1000) {
      logger.warn('轮询超时，已超过5分钟');
      stopPolling();
      setGenerating(false);
      setShowRetry(true);
      message.warning('生成问题超时，请重试');
      return;
    }

    clearPollingTimeout();
    pollingTimeoutRef.current = setTimeout(async () => {
      if (!isPollingRef.current) {
        logger.debug('轮询已取消');
        return;
      }

      try {
        logger.debug('轮询推荐问题，尝试次数:', retryCountRef.current + 1);

        // 检查是否有有效的请求ID
        if (!lastRequestIdRef.current) {
          logger.error('没有有效的请求ID，停止轮询');
          stopPolling();
          setGenerating(false);
          setShowRetry(true);
          message.error('请求ID无效，请重试');
          return;
        }

        const response = await fetchRecommendationQuestionsWithId();

        logger.debug('收到轮询响应');

        if (!response || !response.data) {
          logger.warn('后端返回无效响应');
          handlePollingError(new Error('后端返回无效响应'));
          startPolling(); // 继续轮询
          return;
        }

        const data = response.data.getProjectRecommendationQuestions;
        if (!data) {
          logger.warn('后端未返回数据');
          handlePollingError(new Error('后端未返回数据'));
          startPolling(); // 继续轮询
          return;
        }

        const { status, questions } = data;
        logger.debug(
          '当前状态:',
          status,
          '问题数量:',
          questions?.length || 0,
          '问题数据:',
          questions,
        );

        if (status === RecommendedQuestionsTaskStatus.GENERATING) {
          logger.debug('仍在生成中，继续轮询...');
          startPolling();
        } else if (status === RecommendedQuestionsTaskStatus.FAILED) {
          logger.error('轮询中问题生成失败');
          stopPolling();
          setGenerating(false);
          setShowRetry(true);
          message.error('问题生成失败，请重试');
        } else if (status === RecommendedQuestionsTaskStatus.FINISHED) {
          logger.info('轮询中问题生成完成');
          stopPolling();

          if (Array.isArray(questions) && questions.length > 0) {
            logger.info('设置问题:', questions);

            // 确保每个问题都有必要的字段
            const validQuestions = questions
              .filter((q) => q && typeof q === 'object' && 'question' in q)
              .map((q) => ({
                question: q.question,
                category: q.category || 'General',
                sql: q.sql || '',
              }));

            if (validQuestions.length === 0) {
              logger.warn('过滤后没有有效问题');
              setShowRetry(true);
              setGenerating(false);
              message.warning('没有生成有效的问题，请重试');
              return;
            }

            const groupedQuestions = getGroupedQuestions(validQuestions);
            setRecommendedQuestions(groupedQuestions);
            setGenerating(false);
            setShowRecommendedQuestionsPromptMode(true);
            message.success('问题生成成功');
          } else {
            logger.warn('轮询中没有可用问题');
            setShowRetry(true);
            setGenerating(false);
            message.warning('没有生成任何问题，请重试');
          }
        } else {
          // 处理未知状态
          logger.warn(`未知状态: ${status}，继续轮询`);
          startPolling();
        }
      } catch (error) {
        logger.error('轮询过程中出错:', error);
        handlePollingError(error);
        startPolling(); // 继续轮询，除非达到最大重试次数
      }
    }, POLL_INTERVAL);
  }, [
    clearPollingTimeout,
    fetchRecommendationQuestionsWithId,
    handlePollingError,
    stopPolling,
  ]);

  const onGetRecommendationQuestions = async () => {
    try {
      // 重置所有状态
      setGenerating(true);
      setIsRegenerate(true);
      setShowRetry(false);
      setRecommendedQuestions([]);
      retryCountRef.current = 0;
      isPollingRef.current = true;
      pollingStartTimeRef.current = Date.now();

      // 清除可能存在的旧任务
      lastRequestIdRef.current = null;
      clearPollingTimeout();

      logger.info('开始生成推荐问题...');

      // 添加重试逻辑
      let attempts = 0;
      const maxAttempts = 3; // 增加到3次尝试
      let result;

      while (attempts < maxAttempts) {
        try {
          result = await generateProjectRecommendationQuestions();
          if (result && result.data) break;
        } catch (err) {
          logger.warn(`尝试 ${attempts + 1}/${maxAttempts} 失败:`, err);
          if (attempts === maxAttempts - 1) throw err;
        }
        attempts++;
        await new Promise((r) => setTimeout(r, 2000)); // 增加到2秒后重试
      }

      logger.debug('生成结果:', result);

      if (!result || !result.data) {
        logger.error('生成请求没有返回有效数据');
        throw new Error('创建提问任务失败，请重试');
      }

      // 检查生成结果
      const generatedTaskId =
        result.data.generateProjectRecommendationQuestions;
      logger.debug('生成结果状态:', generatedTaskId);

      if (!generatedTaskId) {
        logger.error('后端返回生成失败或空ID');
        throw new Error('后端生成问题失败，请重试');
      }

      logger.info(`开始获取推荐问题，任务ID: ${generatedTaskId}`);

      // 保存任务ID
      lastRequestIdRef.current = generatedTaskId;

      // 等待一段时间，让后端有时间生成问题
      await new Promise((r) => setTimeout(r, 15000)); // 增加到15秒

      // 尝试获取问题
      let queryAttempts = 0;
      const maxQueryAttempts = 5; // 增加到5次尝试
      let queryResult;

      while (queryAttempts < maxQueryAttempts) {
        try {
          queryResult = await fetchRecommendationQuestionsWithId();
          if (queryResult && queryResult.data) break;
        } catch (err) {
          logger.warn(
            `查询尝试 ${queryAttempts + 1}/${maxQueryAttempts} 失败:`,
            err,
          );
          if (queryAttempts === maxQueryAttempts - 1) throw err;
        }
        queryAttempts++;
        await new Promise((r) => setTimeout(r, 3000)); // 增加到3秒后重试
      }

      logger.debug('查询结果:', queryResult);

      if (!queryResult || !queryResult.data) {
        logger.error('查询请求没有返回有效数据');
        throw new Error('获取推荐问题失败，请重试');
      }

      const data = queryResult.data.getProjectRecommendationQuestions;
      if (!data) {
        logger.error('查询结果中没有数据');
        throw new Error('获取推荐问题失败，请重试');
      }

      const { status, questions } = data;
      logger.debug(
        '当前状态:',
        status,
        '问题数量:',
        questions?.length || 0,
        '问题数据:',
        questions,
      );

      if (status === RecommendedQuestionsTaskStatus.GENERATING) {
        logger.info('问题仍在生成中，开始轮询');
        startPolling();
      } else if (status === RecommendedQuestionsTaskStatus.FAILED) {
        logger.error('问题生成失败');
        throw new Error('问题生成失败，请重试');
      } else if (status === RecommendedQuestionsTaskStatus.FINISHED) {
        if (Array.isArray(questions) && questions.length > 0) {
          logger.info('从初始查询设置问题:', questions);

          // 确保每个问题都有必要的字段
          const validQuestions = questions
            .filter((q) => q && typeof q === 'object' && 'question' in q)
            .map((q) => ({
              question: q.question,
              category: q.category || 'General',
              sql: q.sql || '',
            }));

          if (validQuestions.length === 0) {
            logger.warn('过滤后没有有效问题');
            setShowRetry(true);
            setGenerating(false);
            message.warning('没有生成有效的问题，请重试');
            return;
          }

          const groupedQuestions = getGroupedQuestions(validQuestions);
          setRecommendedQuestions(groupedQuestions);
          setGenerating(false);
          setShowRecommendedQuestionsPromptMode(true);
          message.success('问题生成成功');
        } else {
          logger.warn('初始查询中没有可用问题');
          setShowRetry(true);
          setGenerating(false);
          message.warning('没有生成任何问题，请重试');
        }
      } else {
        // 处理未知状态
        logger.warn(`未知状态: ${status}`);
        setShowRetry(true);
        setGenerating(false);
        message.warning('获取问题状态异常，请重试');
      }
    } catch (error) {
      logger.error('问题生成错误:', error);
      setGenerating(false);
      setShowRetry(true);
      message.error(
        error instanceof Error ? error.message : '创建提问任务失败，请重试',
      );
      handleBackendError(error);
    }
  };

  const buttonProps = useMemo(() => {
    const baseProps = {
      loading: generating,
      onClick: onGetRecommendationQuestions,
      disabled: generating,
    };

    if (showRecommendedQuestionsPromptMode && isRegenerate) {
      return {
        ...baseProps,
        icon: <ReloadOutlined />,
        children: '重新生成',
      };
    }

    return {
      ...baseProps,
      icon: showRetry ? (
        <ReloadOutlined />
      ) : (
        <Icon component={CopilotSVG} className="geekblue-6" />
      ),
      children: generating
        ? '正在生成问题...'
        : showRetry
          ? '重试'
          : '我能问什么 ？',
    };
  }, [generating, isRegenerate, showRetry, showRecommendedQuestionsPromptMode]);

  return {
    recommendedQuestions,
    generating,
    showRetry,
    showRecommendedQuestionsPromptMode,
    buttonProps,
  };
}
